home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ADA Programming Guide
/
ADA Programming Guide.iso
/
ada_pcdp
/
ada
/
tm.ada
< prev
next >
Wrap
Text File
|
1996-01-30
|
6KB
|
213 lines
with Semaphore_Package; use Semaphore_Package;
with Text_IO; use Text_IO;
procedure TM is
type Node_Count is range 0..4;
subtype Node_ID is Node_Count range 1..Node_Count'Last;
task type Nodes is
entry Init(ID: Node_ID; N_I, N_O: Node_Count);
entry Configure(C: Node_ID);
entry Message(M: Integer; ID: Node_ID);
entry Signal(ID: Node_ID);
end Nodes;
Node: array(Node_ID) of Nodes;
task body Nodes is
type Edge is
record
Exists: Boolean := False;
Active: Boolean := False;
Marker_Received: Boolean := False;
end record;
Incoming: array(Node_ID) of Edge;
Outgoing: array(Node_ID) of Edge;
First_Edge: Node_Count := 0;
N_In, N_Out: Node_Count := 0;
N_Signals: Natural := 0;
pragma Volatile(N_Signals);
pragma Volatile(First_Edge);
pragma Volatile(Incoming);
pragma Volatile(Outgoing);
I: Node_ID;
S: Binary_Semaphore := Init(1);
Received_ID: Node_ID;
Received_Data: Integer;
task Main_Process is
entry Init;
end Main_Process;
task body Main_Process is
Count: Integer := 0;
Markers_Sent: Boolean := False;
procedure Send_Messages(Data: Integer) is
begin
for J in Node_ID loop
if Outgoing(J).Exists then
Put_Line(" " & Node_ID'Image(I) & " sending " &
Integer'Image(Data) & " to " &
Node_ID'Image(J));
if not Outgoing(J).Active then
Outgoing(J).Active := True;
Wait(S);
N_Signals := N_Signals + 1;
Signal(S);
end if;
Node(J).Message(Data, I);
end if;
end loop;
end Send_Messages;
function Decide_to_Terminate return Boolean is
procedure Send_Signals(ID: Node_ID) is
begin
Put_Line(" " & Node_ID'Image(I) & " sending signal to " &
Node_ID'Image(ID));
Node(ID).Signal(I);
Incoming(ID).Active := False;
end Send_Signals;
begin
for J in Node_ID loop
if J /= First_Edge and then
Incoming(J).Active then
Send_Signals(J);
end if;
end loop;
if N_Signals = 0 then
if I = 1 then
Put_Line(" " & Node_ID'Image(I) & " program terminated ");
elsif First_Edge /= 0 then
Send_Signals(First_Edge);
First_Edge := 0;
end if;
return True;
else
return False;
end if;
end Decide_to_Terminate;
function Received_Markers return Boolean is
begin
for J in Node_ID loop
if Incoming(J).Exists and then
not Incoming(J).Marker_Received then
return False;
end if;
end loop;
return True;
end Received_Markers;
begin
accept Init;
if I = 1 then
Send_Messages(Count);
Send_Messages(Count);
Send_Messages(-1);
loop
exit when Decide_to_Terminate;
delay 0.01;
end loop;
else
loop
if Count < 5 then
if First_Edge /= 0 then
Count := Count + 1;
Send_Messages(Count);
end if;
elsif not Markers_Sent then
if Incoming(First_Edge).Marker_Received then
Send_Messages(-1);
Markers_Sent := True;
end if;
elsif Received_Markers then
loop
exit when Decide_to_Terminate;
delay 0.01;
end loop;
exit;
end if;
delay 0.01;
end loop;
end if;
end Main_Process;
begin
accept Init(ID: Node_ID; N_I, N_O: Node_Count) do
I := ID;
N_In := N_I;
N_Out := N_O;
end Init;
for J in 1..N_In loop
accept Configure(C: Node_ID) do
Incoming(C).Exists := True;
end Configure;
end loop;
for J in 1..N_Out loop
accept Configure(C: Node_ID) do
Outgoing(C).Exists := True;
end Configure;
end loop;
Main_Process.Init;
loop
select
accept Message(M: Integer; ID: Node_ID) do
Put_Line(" " & Node_ID'Image(I) & " received " &
Integer'Image(M) & " from " &
Node_ID'Image(ID));
Received_ID := ID;
Received_Data := M;
end Message;
if Received_Data < 0 then
Incoming(Received_ID).Marker_Received := True;
else
if First_Edge = 0 then
First_Edge := Received_ID;
end if;
end if;
if not Incoming(Received_ID).Active then
Incoming(Received_ID).Active := True;
end if;
or
accept Signal(ID: Node_ID) do
Put_Line(" " & Node_ID'Image(I) & " received signal from " &
Node_ID'Image(ID));
Received_ID := ID;
end Signal;
Outgoing(Received_ID).Active := False;
Wait(S);
N_Signals := N_Signals - 1;
Signal(S);
or
terminate;
end select;
end loop;
end Nodes;
begin
Node(1).Init(1,0,2);
Node(1).Configure(2); Node(1).Configure(3);
Node(2).Init(2,2,2);
Node(2).Configure(1); Node(2).Configure(3);
Node(2).Configure(3); Node(2).Configure(4);
Node(3).Init(3,3,1);
Node(3).Configure(1); Node(3).Configure(2);
Node(3).Configure(4); Node(3).Configure(2);
Node(4).Init(4,1,1);
Node(4).Configure(2); Node(4).Configure(3);
end TM;